package com.netty;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.redis.RedisUtil;
import com.util.BeanUtil;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelId;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * 处理服务端 channel.
 */
public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1)

	protected final Logger logger = LoggerFactory.getLogger(this.getClass());

	public static ConcurrentHashMap<String, ChannelHandlerContext> channelMap = new ConcurrentHashMap<String, ChannelHandlerContext>();

	public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

	public static Map<ChannelId, Object> markMap = new HashMap<ChannelId, Object>();

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) { // (2)
		try {
			Channel incoming = ctx.channel();
			ByteBuf buf = (ByteBuf) msg;
			byte[] req = new byte[buf.readableBytes()];
			buf.readBytes(req);
			String dataLogger = BeanUtil.convertByteArrayToHexStr(req, 8, 16);
			String allData = BeanUtil.convertByteArrayToHexStr(req);
			logger.info("dataLogger:" + dataLogger + "-------" + allData);
			channelMap.put(dataLogger, ctx);
			markMap.put(incoming.id(), dataLogger);
			RedisUtil.getJedis().set(dataLogger + "_" + System.currentTimeMillis(), allData);
		} finally {
			// ctx.write(msg); // (1)
			// ctx.flush(); // (2)
			int i = 2000;
			// 把int转换为字节数组
			byte[] result = new byte[4];
			result[0] = (byte) (i >>> 24);// 取最高8位放到0下标
			result[1] = (byte) (i >>> 16);// 取次高8为放到1下标
			result[2] = (byte) (i >>> 8); // 取次低8位放到2下标
			result[3] = (byte) (i); // 取最低8位放到3下标

			ByteBuf encoded = ctx.alloc().buffer();
			encoded.writeBytes(result);
			for (Channel channel : channels) {
				encoded.retain();
				channel.write(encoded);
				channel.flush();
				// break;
			}
		}

	}

	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		Channel incoming = ctx.channel();
		channels.add(incoming);
		logger.info("Client:" + incoming.remoteAddress() + "加入");
	}

	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		Channel incoming = ctx.channel();
		remove(incoming);
		logger.info("Client:" + incoming.remoteAddress() + "离开:" + channels.size());
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
		Channel incoming = ctx.channel();
		remove(incoming);
		// 当出现异常就关闭连接
		logger.info(cause.toString());
		ctx.close();
	}

	private void remove(Channel incoming) {
		if (markMap.containsKey(incoming.id())) {
			String dataLogger = markMap.get(incoming.id()).toString();
			channelMap.remove(dataLogger);
			markMap.remove(incoming.id());
		}
	}

}